//
//  RNManager.m
//  AwesomeProject
//
//  Created by zhoufei on 2024/3/14.
//

#import "RNManager.h"
#import <React-RCTAppDelegate/RCTAppSetupUtils.h>
#import <React/RCTBundleURLProvider.h>


@implementation RNManager
+ (instancetype)sharedInstance {
  static RNManager *shareObj;
  static dispatch_once_t onceKey;
  dispatch_once(&onceKey, ^{
    shareObj = [[super allocWithZone:nil] init];
  });
  return shareObj;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone {
  return [self sharedInstance];
}

- (instancetype)copyWithZone:(struct _NSZone *)zone {
  return self;
}



- (RNContainerController *)loadWithModuleName:(NSString *)moduleName initialProps:(NSDictionary *)initialProps
{
  self.initialProps = initialProps;
  self.moduleName = moduleName;
  
  BOOL enableTM = NO;
  BOOL enableBridgeless = NO;
  BOOL fabricEnabled = NO;
#if RCT_NEW_ARCH_ENABLED
  enableTM = self.turboModuleEnabled;
  enableBridgeless = self.bridgelessEnabled;
  fabricEnabled = [self fabricEnabled];
#endif
  NSDictionary *initProps = updateInitialPropsOn([self prepareInitialProps], fabricEnabled);

  RCTAppSetupPrepareApp([UIApplication sharedApplication], enableTM);

  UIView *rootView;

  if (enableBridgeless) {
#if RCT_NEW_ARCH_ENABLED
    // Enable native view config interop only if both bridgeless mode and Fabric is enabled.
    RCTSetUseNativeViewConfigsInBridgelessMode(fabricEnabled);

    // Enable TurboModule interop by default in Bridgeless mode
    RCTEnableTurboModuleInterop(YES);
    RCTEnableTurboModuleInteropBridgeProxy(YES);

    [self createReactHost];
    [self unstable_registerLegacyComponents];
    [RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
    RCTFabricSurface *surface = [_reactHost createSurfaceWithModuleName:self.moduleName initialProperties:initProps];

    RCTSurfaceHostingProxyRootView *surfaceHostingProxyRootView = [[RCTSurfaceHostingProxyRootView alloc]
        initWithSurface:surface
        sizeMeasureMode:RCTSurfaceSizeMeasureModeWidthExact | RCTSurfaceSizeMeasureModeHeightExact];

    rootView = (RCTRootView *)surfaceHostingProxyRootView;
#endif
  } else {
    if (!self.bridge) {
      self.bridge = [self createBridgeWithDelegate:self launchOptions:@{}];
    }
#if RCT_NEW_ARCH_ENABLED
    self.bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:self.bridge
                                                                 contextContainer:_contextContainer];
    self.bridge.surfacePresenter = self.bridgeAdapter.surfacePresenter;

    [self unstable_registerLegacyComponents];
    [RCTComponentViewFactory currentComponentViewFactory].thirdPartyFabricComponentsProvider = self;
#endif

    rootView = [self createRootViewWithBridge:self.bridge moduleName:self.moduleName initProps:initProps];
  }
  RNContainerController *rootViewController = [self createRootViewController];
  [self setRootView:rootView toRootViewController:rootViewController];

  return rootViewController;
}






- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{

  return [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"jsbundle"];

//  return [self getBundleURL];
}

- (NSURL *)getBundleURL
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}


- (NSDictionary *)prepareInitialProps
{
  return self.initialProps;
}

- (RNContainerController *)createRootViewController
{
  return [RNContainerController new];
}



NSDictionary *updateInitialPropsOn(NSDictionary *initialProps, BOOL isFabricEnabled)
{
#ifdef RCT_NEW_ARCH_ENABLED
  NSMutableDictionary *mutableProps = [initialProps mutableCopy] ?: [NSMutableDictionary new];
  // Hardcoding the Concurrent Root as it it not recommended to
  // have the concurrentRoot turned off when Fabric is enabled.
  mutableProps[kRNConcurrentRoot] = @(isFabricEnabled);
  return mutableProps;
#else
  return initialProps;
#endif
}


@end
